package breeze.framework.json;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
 * @author breeze
 * @date 2020年6月18日
 * @email breeze_java@163.com
 * @description
 * @see breeze.file.JacksonTest
 */
@SuppressWarnings("deprecation")
public class Jackson {

	public static String Default_Object_Start = "{";
	public static String Default_Object_End = "}";
	public static String Default_Object = Default_Object_Start + Default_Object_End;
	
	public static String Default_Array_Start = "[";
	public static String Default_Array_End = "]";
	public static String Default_Array = Default_Array_Start + Default_Array_End;
	
	
	private static ObjectMapper mapper = new ObjectMapper();
	
	/**
	 * 通过反射转化任何属性，不管是否提供了公有的get方法,包括静态属性
	 * mapper.setVisibilityChecker(VisibilityChecker.Std.defaultInstance().withFieldVisibility(Visibility.ANY));
	 */
	static{
		mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true) ;
		mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true) ;
		mapper.configure(Feature.ALLOW_COMMENTS, true);
		mapper.configure(Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);//允许value中含有反斜杠等特殊字符
		mapper.configure(Feature.ALLOW_YAML_COMMENTS, true);
		mapper.configure(Feature.ALLOW_TRAILING_COMMA, true);//允许出现不合理的格式错误.比如结尾有多余逗号

		
//		/**
//		 * 使Jackson支持utf-8
//		 */
		mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);//当找不到对应的序列化时忽略此字段
		SimpleModule module = new SimpleModule();
		module.addSerializer(String.class,new StringUnicodeSerializer());
		module.addDeserializer(String.class, new StringUnicodeDeSerializer());
		mapper.registerModule(module);
		
//		mapper.setSerializationInclusion(Include.NON_NULL);
		//重写类中的serialize，指定出现null值是返回""字符串
		mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
			@Override
			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
				jsonGenerator.writeString("");
			}
		});
	}
	
	public static String toString(Object obj){
		try {
			if(null == obj) {
				return Default_Object;
			}
			if(obj.getClass() == File.class) {
				File file = (File) obj;
				ObjectNode node = mapper.createObjectNode();
				node.put("name", file.getName());
				if(file.isFile()) {
					node.put("size", (int)(file.length()/1024/1024) + "m");
				}else {
					node.put("size", "");
				}
				node.put("updated_time",new Date(file.lastModified()).toLocaleString());
				node.put("is_hidden", file.isHidden());
				node.put("is_file", file.isFile());
//				node.put("parent", file.getParent().replace("\\", "/"));
				return node.toString();
			}else {
				return mapper.writeValueAsString(obj);
			}
		} catch (IOException e) {
			e.printStackTrace();
			return null == obj ? Default_Object : obj.toString();
		}
	}
	
	public static String toString(List<File> files) {
		String result = Jackson.Default_Array_Start;
		for (int i = 0; i < files.size(); i++) {
			result += Jackson.toString(files.get(i));
			if(i != files.size() - 1) {
				result += ",";
			}
		}
		return result + Jackson.Default_Array_End;
	}
	
	public static ArrayNode newArray() {
		return mapper.createArrayNode();
	}
	
	public static <T> T toObject(String jsonString,Class<T> cls){
		try {
			return mapper.readValue(jsonString, cls);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * 读取有效的json文件. 
	 */
	public static JsonNode read(String catalog) {
		try {
			return mapper.readTree(catalog);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * TODO 是直接覆写还是修改?
	 */
	public static boolean write(JsonNode node,String catalog) {
		try {
			mapper.writerWithDefaultPrettyPrinter().writeValue(new File(catalog), node);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public static ObjectMapper getMapper() {
		return mapper;
	}

	public static void setMapper(ObjectMapper mapper) {
		Jackson.mapper = mapper;
	}

}
